/*
 *	Panel Item
 * 	Responsible for grouping items in panels.
 */
 
 jt.module('PanelItem', function(context) {
	
	// useful shorthands
	var canvas = context.canvas,
		settings = context.settings,
		gh = context.settings.grid.h,
		gv = context.settings.grid.v,
		fn = context.fn,
	
	items = {},
	itemParents = {},
	panels = {},
	panelItems = {},
	dragOverPanel,
	draggedPanel,
	hoveredPanel,
	dragInsideIndex,
	itemGrid,

	itemAttributes = ['parent'],
	panelAttributes = ['x','y','title', 'w', 'h', 'colums', 'rows'],
	
	cursor = {
		x: 0,
		y: 0,
		h: 0,
		v: 0
	};

	settings = util.extend({
		edit: true,
		snapPanels: true,
		snapTolerance: 12,
		panelAnimAlignSpeed: 150
	}, settings);

	// Get exposed item grid
	context.on('itemGridReady', function(grid) { itemGrid = grid; });

	// Helper math functions
	function posFromGrid(posX, posY, width, height, panelX, panelY) {
		
		var px = panelX || 0,
			py = panelY || 0;

		return {
			x: px + (posX * gh) + Math.abs(gh - (width || 0)) / 2,
			y: py + (posY * gv) + Math.abs(gv - (height || 0)) / 2 + 8
		}
	};
	
	function gridFromPos(posX, posY) {
		return {
			x: posX / gh,
			y: posY / gv,
		}
	};

	/**
	 * Moves panel with it's items to the specified position
	 * @param {[type]} panel Panel instace
	 * @param {[type]} x New x position
	 * @param {[type]} y New y position
	 * @param {[type]} width New width of the panel // todo
	 * @param {[type]} height New height of the panel // todo
	 */
	function setPanelPos(panel, x, y, width, height) {
		var handle = panel.handle,	
			container = panel.container;	
		
		util.extend(panel.ref, gridFromPos(x, y));
		
		var handlePos = {x: dx + panel.titleBackground.ox, y: dy + panel.titleBackground.oy};
		
		handle.attr(handlePos);
		
		var bbox = handle.getBBox();
		container.attr({x: bbox.x, y: bbox.y});

		if(panelItems[this.ref.id]) {		
			for(var i = 0, len = panelItems[this.ref.id].length; i < len; i++) {
				var item = panelItems[this.ref.id][i];
				
				var itemPos = posFromGrid(i, 0, item.ref.w, item.ref.h, bbox.x, bbox.y);

				item.handle.attr({
					x: itemPos.x, 
					y: itemPos.y
				});

				item.elements.attr({
					x: itemPos.x, 
					y: itemPos.y
				});
			}
		}

		util.extend(panel.ref,{
			x: bbox.x,
			y: bbox.y,
			width: bbox.width,
			height: bbox.height 
		});
	};

	/**
	 * Removes specified item from panel
	 * @param  {item} item Item object to remove
	 * @param  {panel} panel Optional panel if item.ref.parent is not set
	 * @return {bool} true if item removed otherwise false
	 */
	function removeItemFromPanel(item, panel) {
		// if item belongs to any panel
		if(item && (itemParents[item.ref.id] || panel)) {
			
			var panel = panels[item.ref.parent] || panel,
			itemIdx = panelItems[panel.ref.id].indexOf(item);

			if(itemIdx === -1)
				return false;
			
			item.ref.parent = null;
			delete itemParents[item.ref.id];
			panelItems[panel.ref.id].remove(item);

			// remove panel hover effect from panel and call onMouseOut
			
			panel.container.attr({height: gv + panel.titleBackground.getBBox().height / 2, width: panelItems[panel.ref.id].length * gh});
			panel.title.attr({translation: '' + ((panel.container.getBBox().width - panel.title.getBBox().width) / 2) + ',' + (panel.title.attr('font-size') - 3)});
			panel.titleShadow.attr({translation: '' + ((panel.container.getBBox().width - panel.title.getBBox().width) / 2 + 1) + ',' + (panel.title.attr('font-size') - 2)});
			panel.titleBackground.attr({width:  panelItems[panel.ref.id].length * gh});
			
			var panelLen = panelItems[panel.ref.id].length,
				bbox = panel.container.getBBox();
		
			for(i = 0; i < panelLen; i++) {
				var it = panelItems[panel.ref.id][i];
				it.handle.attr({scale: '1' });

				var itemPos = posFromGrid(i, 0, it.ref.w, it.ref.h, bbox.x, bbox.y);

				util.extend(it.ref, {
					x: i,
					y: 0
				})

				it.handle.stop().attr({
					x: itemPos.x, 
					y: itemPos.y
				});

				it.elements.stop().attr({
					x: itemPos.x, 
					y: itemPos.y
				});
				
				context.event('panelItemPosChanged', it)	
			}

			util.extend(panel.ref,{
				x: bbox.x,
				y: bbox.y,
				width: bbox.width,
				height: bbox.height 
			});

			context.event('removedItemFromPanel', panel, item);
			
			if(!panelItems[panel.ref.id].length) {
				context.removeItem(panel.ref.id);
			}

			return true;
		}

		return false;
	};

	/**
	 * Refresh position of items belongs to specified panel
	 * @param  {panel} panel Panel which items will be refreshed
	 */
	function refreshPanelItems(panel) {

		var items = panelItems[panel.ref.id],
			containerBBox = panel.container.getBBox();

		for(var i = 0, len = items.length; i < len; i++) {
			
			var it = items[i];

			util.extend(it.ref, {
				x: i,
				y: 0
			})

			var itemPos = posFromGrid(i, 0, it.ref.w, it.ref.h, containerBBox.x, containerBBox.y);

			it.handle.attr({
				x: itemPos.x, 
				y: itemPos.y
			});	

			it.elements.attr({
				x: itemPos.x, 
				y: itemPos.y
			});	

			context.event('panelItemPosChanged', it)
		}
	}
	
	// Drag event handlers
	var onDragStart = function (x, y) {

		if(!settings.edit || !this.canDrag)
			return;
		
		var handle = this.handle,
		container = this.container;	
		
		this.titleBackground.ox = this.titleBackground.attr('x');
		this.titleBackground.oy = this.titleBackground.attr('y');
		handle.toFront();
		
		if(panelItems[this.ref.id]) {		
			for(var i = 0, len = panelItems[this.ref.id].length; i < len; i++) {
				var item = panelItems[this.ref.id][i];

				item.handle.toFront();
				item.titleShadow.toFront();
				item.title.toFront();
			}
		}

		this.dragged = true;
		context.container.style.cursor = 'move';
		context.event('panelDragStart', this);
	},
	
	onDragMove = function (dx, dy) {
		
		if(!settings.edit || !this.canDrag)
			return;
		
		var handle = this.handle,	
		container = this.container;	
		
		var handlePos = {x: dx + this.titleBackground.ox, y: dy + this.titleBackground.oy};

		if(settings.snapPanels && !context.globalEvent.ctrlKey) {
			for(var panel in panels) {
				if(panels.hasOwnProperty(panel) && panels[panel] && panels[panel] !== this) {
					
					var pbbox = {
						x: panels[panel].title.attr('x'),
						y: panels[panel].title.attr('y')
					}

					if(Math.abs(handlePos.x - pbbox.x) < settings.snapTolerance) {
						handlePos.x = pbbox.x;
					}

					if(Math.abs(handlePos.y - pbbox.y) < settings.snapTolerance) {
						handlePos.y = pbbox.y;
					}

				}
			}
		}
		
		handle.attr(handlePos);
		
		var bbox = this.titleBackground.getBBox();
		container.attr({x: bbox.x, y: bbox.y});

		if(panelItems[this.ref.id]) {		
			for(var i = 0, len = panelItems[this.ref.id].length; i < len; i++) {
				var item = panelItems[this.ref.id][i];
				
				var itemPos = posFromGrid(i, 0, item.ref.w, item.ref.h, bbox.x, bbox.y);

				item.handle.attr({
					x: itemPos.x, 
					y: itemPos.y
				});

				item.elements.attr({
					x: itemPos.x, 
					y: itemPos.y
				});
			}
		}

		var panelPos;

		if(this.ref.grid === true) {
			panelPos = gridFromPos(cursor.x, cursor.y)
		} else {
			panelPos = bbox;
		}

		util.extend(this.ref,{
			x: panelPos.x,
			y: panelPos.y
		});
	},
	
	onDragEnd = function () {
		
		if(!settings.edit || !this.canDrag)
			return;
			
		var handle = this.handle;	
		container = this.container;	
		
		util.extend(this.ref, gridFromPos(cursor.x, cursor.y));
			
		var bbox = container.getBBox();

		if(panelItems[this.ref.id]) {		
			for(var i = 0, len = panelItems[this.ref.id].length; i < len; i++) {
				var item = panelItems[this.ref.id][i];
				
				var itemPos = posFromGrid(i, 0, item.ref.w, item.ref.h, bbox.x, bbox.y);

				item.handle.stop().attr({
					x: itemPos.x, 
					y: itemPos.y
				});

				item.elements.stop().attr({
					x: itemPos.x, 
					y: itemPos.y
				});
				
				item.handle.animate({scale: '1' }, 100, '>');
				item.handle.animate({opacity: 1 }, 300, '>').toFront();
				item.elements.attr({'opacity': '1'});
			}
		}

		var panelPos;

		if(this.ref.grid === true) {
			panelPos = gridFromPos(cursor.x, cursor.y)
		} else {
			panelPos = bbox;
		}

		util.extend(this.ref,{
			x: panelPos.x,
			y: panelPos.y
		});

		this.dragged = false;
		context.container.style.cursor = 'default';
		context.event('panelDragEnd', this);
	},

	onMouseOver = function(duration) {
		this.titleBackground.stop().animate({opacity: 0.6}, '200', 'linear');
	},

	onMouseOut = function(duration) {
		this.titleBackground.stop().animate({opacity: 0.3}, '200', 'linear');
	};

	// Panel prototype
	function Panel() {};

	var panelProto = Panel.prototype = {
		
	},

	// Panel ref prototype (reference object is extended by this object's methods)
	panelRefProto = {
		getItems: function() {
			if(panelItems[this.id]) {
				return panelItems[this.id].map(function(item) { return item.ref; });
			}
		}
	}

	context.on('panelDragStart', function(panel) {
		draggedPanel = panel;
	});

	context.on('panelDragEnd', function(panel) {
		draggedPanel = null;
	});

	return {
		
		events: {
			/*
			 *	Summary: Initialize module event handler
			 */
			init: function() {
				context.log('[PanelItemManager] init');
			},
			
			/*
			 *	Summary: addItem event handler. Responsible for building panel items and adding other items to them.
			 *	Arguments: item object reference and settings.
			 */
			addItem: function(item, itemSettings) {
				
				if (item.classes.indexOf('panel') > -1 && !panels[item.id]) {

					// Item settings
					var	it = {};
					it.ref = util.extend(item, panelRefProto);

					var settings = util.extend({
						title: '',
						x: 0,
						y: 0,
						width: 0,
						height: 0,
						grid: false
					}, itemSettings);
					
					util.extend(it.ref, settings);
					
					var itemPos;
					
					if(it.ref.grid === true) {
						itemPos = posFromGrid(settings.x, settings.y);
					} else {
						itemPos = {x: it.ref.x, y: it.ref.y};
					}

					it.title = canvas.text(itemPos.x, itemPos.y, settings.title)
					.attr({
						'font-family': '"Lucida Grande","Lucida Sans Unicode",Helvetica, Arial, Verdana',
						'font-weight': 'normal',
						'font-style': 'normal',
						'font-size': '15',
						'fill': '#FFF',
						'stroke': 'none',
						'text-anchor': 'start'});

					it.titleShadow = canvas.text(itemPos.x, itemPos.y, settings.title)
					.attr({
						'font-family': '"Lucida Grande","Lucida Sans Unicode",Helvetica, Arial, Verdana',
						'font-weight': 'normal',
						'font-style': 'normal',
						'font-size': '15',
						'fill': '#000',
						'text-anchor': 'start'}).toBack();

					it.titleBackground = canvas.rect(itemPos.x, itemPos.y, settings.title ? it.title.getBBox().width + 24 : 0, settings.title ? it.title.attr('font-size') * 1.2 + 9 : 0, 3)
					.attr({
						'fill': '#000',
						'stroke': 'none',
						'opacity': '0.3'})
					.toBack();

					it.container = canvas.rect(it.titleBackground.getBBox().x, it.titleBackground.getBBox().y, 0, 0, 4)
					.attr({
						'fill': '#000',
						'stroke': 'none',
						'opacity': '0.4'})
					.toBack();
							
				//	it.title.attr({transform: '' + ((it.container.getBBox().width - it.title.getBBox().width) / 2) + ',' + (it.title.attr('font-size') - 3)});
				//	it.titleShadow.attr({transform: 't' + ((it.container.getBBox().width - it.title.getBBox().width) / 2 + 1) + ',' + (it.title.attr('font-size') - 2)});
					
					//it.titleBackground.node.style.cursor = 'move';
					//it.title.node.style.cursor = 'move';
					
					it.handle = canvas.set();
					it.handle.push(it.titleBackground, it.titleShadow, it.title);
					
					it.handle.drag(onDragMove, onDragStart, onDragEnd, it, it, it);
					it.canDrag = true;
					it.draggable = false;
					it.dragged = false;

					// add events
					it.handle.mousemove(function (event) {
					
						if(settings.edit && it.canDrag) {	
							var bbox = this.getBBox();
							cursor.x = Raphael.snapTo(gh, bbox.x, gh);
							cursor.y = Raphael.snapTo(gv, bbox.y, gv) + gv;
						}
					});		
					
					// TODO
					//it.container.hover(onMouseOver, onMouseOut, it, it);
					//it.handle.hover(onMouseOver, onMouseOut, it, it);

					// Put to panel all items belongs to it (because of creating item after item collision event)
					if(panelItems[item.id]) {
						
						it.container.attr({height: gv + it.titleBackground.getBBox().height / 2, width:  panelItems[item.id].length * gh});
						it.titleBackground.attr({width:  panelItems[item.id].length * gh});
						
						it.title.attr({translation: '' + ((it.container.getBBox().width - it.title.getBBox().width) / 2) + ',' + (it.title.attr('font-size') - 3)});
						it.titleShadow.attr({translation: '' + ((it.container.getBBox().width - it.title.getBBox().width) / 2 + 1) + ',' + (it.title.attr('font-size') - 2)});
						
						var bbox = it.container.getBBox();

						for(var i = 0, len = panelItems[item.id].length; i < len; i++) {
							
							var iterator = panelItems[item.id][i];
							iterator.ref.parent = item.id;
							
							iterator.selected = false;

							// TODO
							//iterator.handle.hover(onMouseOver, onMouseOut, it, it);
							//iterator.elements.hover(onMouseOver, onMouseOut, it, it);
					
							var	itemPos = posFromGrid(i, 0, iterator.ref.w, iterator.ref.h, bbox.x, bbox.y);

							util.extend(iterator.ref, {
								x: i,
								y: 0
							})

							context.event('panelItemPosChanged', iterator);

							iterator.handle.stop().attr({
								x: itemPos.x, 
								y: itemPos.y
							});

							iterator.elements.stop().attr({
								x: itemPos.x, 
								y: itemPos.y
							});	

							iterator.handle.show().animate({ opacity: 1}, 200, '>');
							iterator.elements.show().animate({ opacity: 1},200, '>');
						}
					}

					// set ref attributes
					
					var bbox = it.container.getBBox();

					util.extend(it.ref,{
						x: it.ref.grid === true ? itemPos.x : bbox.x,
						y: it.ref.grid === true ? itemPos.y : bbox.y,
						width: bbox.width,
						height: bbox.height,
					});

					panels[item.id] = it;			
					context.event('addPanelItem', it, settings);	
				}
			},
			
			addDefaultItem: function(item, itemSettings) {
				// add to local storage of default items (for attributes change)
				items[item.ref.id] = item;

				if(!item.ref.parent)
					return;

				var panel = panels[item.ref.parent];
					
				if(!panel)
					return;

				if(!panelItems[item.ref.parent])
					panelItems[item.ref.parent] = [];

				panelItems[item.ref.parent].splice(item.ref.x, 0, item);
				itemParents[item.ref.id] = item.ref.parent;

				itemGrid.removeItem(item.ref);

				if(panel) {
					
					// TODO
					//item.handle.hover(onMouseOver, onMouseOut, panel, panel);
					//item.elements.hover(onMouseOver, onMouseOut, panel, panel);

					panel.container.attr({height: gv + panel.titleBackground.getBBox().height / 2, width:  panelItems[item.ref.parent].length * gh});
					panel.title.attr({translation: '' + ((panel.container.getBBox().width - panel.title.getBBox().width) / 2) + ',' + (panel.title.attr('font-size') - 3)});
					panel.titleShadow.attr({translation: '' + ((panel.container.getBBox().width - panel.title.getBBox().width) / 2 + 1) + ',' + (panel.title.attr('font-size') - 2)});
					panel.titleBackground.attr({width:  panelItems[item.ref.parent].length * gh});
			
					var bbox = panel.container.getBBox(),
						itemPos = posFromGrid(panelItems[item.ref.parent].length - 1, 0, item.ref.w, item.ref.h, bbox.x, bbox.y);

					item.handle.stop().attr({
						x: itemPos.x, 
						y: itemPos.y
					});

					item.elements.stop().attr({
						x: itemPos.x, 
						y: itemPos.y
					});	

					util.extend(panel.ref,{
						width: bbox.width,
						height: bbox.height 
					});

					//refreshPanelItems(panel);
				}
			},
			
			removeItem: function(itemId) {
			
				var panel = panels[itemId];
			
				if(!panel) {
					return;
				}
				
				context.event('removePanelItem', panel);
			
				panel.handle.remove();
				panel.container.remove();
				panels[itemId] = null;
				
				if(dragOverPanel === panel) {
					dragOverPanel = null;
				}

				panel = null;	

			},
			
			removeDefaultItem: function(item) {
				removeItemFromPanel(item);
			},
			
			itemDragStart: function(item, pos) {
				removeItemFromPanel(item);
			},
			
			itemDragEnd: function(item, pos) {
				
				// if there is item above panel (dragOverPanel is set to this panel), 
				// we can add item to it at specified position.
				if(dragOverPanel) {
					
					var panel = dragOverPanel,
						items = panelItems[dragOverPanel.ref.id],
						containerBBox = dragOverPanel.container.getBBox();

					item.ref.parent = panel.ref.id;
					
					items.splice(dragInsideIndex + 1, 0, item);
					itemParents[item.ref.id] = item.ref.parent;

					itemGrid.removeItem(item.ref);

					// TODO
					//item.handle.hover(onMouseOver, onMouseOut, panel, panel);
					//item.elements.hover(onMouseOver, onMouseOut, panel, panel);

					panel.container.attr({height: gv + panel.titleBackground.getBBox().height / 2, width:  panelItems[item.ref.parent].length * gh});
					panel.title.attr({translation: '' + ((panel.container.getBBox().width - panel.title.getBBox().width) / 2) + ',' + (panel.title.attr('font-size') - 3)});
					panel.titleShadow.attr({translation: '' + ((panel.container.getBBox().width - panel.title.getBBox().width) / 2 + 1) + ',' + (panel.title.attr('font-size') - 2)});
					panel.titleBackground.attr({width:  panelItems[item.ref.parent].length * gh});

					item.handle.stop().attr({ opacity: 1});
					item.elements.stop().attr({ opacity: 1});
						
					item.selected = false;

					for(var i = 0, len = items.length; i < len; i++) {
						
						var it = items[i];

						util.extend(it.ref, {
							x: i,
							y: 0
						})

						context.event('panelItemPosChanged', it);

						var itemPos = posFromGrid(i, 0, it.ref.w, it.ref.h, containerBBox.x, containerBBox.y);

						it.handle.stop().animate({
							x: itemPos.x, 
							y: itemPos.y
						},  settings.panelAnimAlignSpeed, '>');	

						it.elements.stop().animate({
							x: itemPos.x, 
							y: itemPos.y
						},  settings.panelAnimAlignSpeed, '>');	
						
						it.handle.animate({scale: '1' }, 100, '>');
					}

					var bbox = panel.container.getBBox();

					util.extend(panel.ref,{
						width: bbox.width,
						height: bbox.height 
					});

					context.event('addedItemToPanel', panel, item);
				}
			},
			
			itemDragCollision: function(item, itemBelow, pos) {

				if(dragOverPanel) {
					context.event('itemDragEnd', item, pos);
					return;
				}

				// here we have to create panel
				var newPanelId = 'item_' + context.getNextId();
				
				panelItems[newPanelId] = [];
				panelItems[newPanelId].push(itemBelow);
				panelItems[newPanelId].push(item);
				
				// set parent map references
				itemParents[itemBelow.ref.id]  = newPanelId;
				itemParents[item.ref.id] = newPanelId;

				// removing items from item grid
				itemGrid.removeItem(item.ref);
				itemGrid.removeItem(itemBelow.ref);
	
				// creating panel
				context.addItem({id: newPanelId, classes: ['panel'], x: itemBelow.ref.x * gh, y: itemBelow.ref.y * gv, title: itemBelow.ref.title});
			},

			itemDragMove: function(item, pos) {
				
				var panel,
					activePanel;
	
				for(panel in panels) {
					
					if(!panels[panel]) {
						dragOverPanel = activePanel;
						dragInsideIndex = null;
						continue;
					}

					var containerBBox = panels[panel].container.getBBox();
					
					// test if item is inside panel	
					if(pos.x <= (containerBBox.x + containerBBox.width) && pos.x >= containerBBox.x
					&& pos.y <= (containerBBox.y + containerBBox.height) && pos.y >= containerBBox.y) {
						activePanel = panels[panel];
						
						context.event('itemCursorHide');
						
						var items = panelItems[activePanel.ref.id],
							itemsLength = items.length,
							insideIndex = Math.round(((pos.x - containerBBox.x) - gh )/ gh),
							itemBefore = items[insideIndex],
							itemAfter = items[insideIndex + 1];
						
						if(dragInsideIndex === insideIndex && activePanel === dragOverPanel) {
							continue;
						}

						dragInsideIndex = insideIndex;
						dragOverPanel = activePanel;
						break;

					}
				}

				if(activePanel === undefined) {
					context.event('itemCursorShow');
					dragOverPanel = activePanel;
					dragInsideIndex = null;
				}
				
			},

			mouseMove: function(e, x, y) {
				var itPanel,
					activePanel,
					pos = {
						x: x,
						y: y	
					};
						
				if(draggedPanel) {

					if(draggedPanel !== hoveredPanel) {
						hoveredPanel && context.event('panelMouseLeave', hoveredPanel, pos);
						context.event('panelMouseEnter', draggedPanel, pos);	
						hoveredPanel = draggedPanel;	
					}
					
					return;
				}
	
				for(panel in panels) {
					
					itPanel = panels[panel];

					if(!itPanel) continue;

					var containerBBox = itPanel.container.getBBox();
					
					// test if cursor is inside panel	
					if(pos.x <= (containerBBox.x + containerBBox.width) && pos.x >= containerBBox.x
					&& pos.y <= (containerBBox.y + containerBBox.height) && pos.y >= containerBBox.y) {
						
						activePanel = panels[panel];

						if(activePanel !== hoveredPanel) {
							hoveredPanel && context.event('panelMouseLeave', hoveredPanel, pos);
							context.event('panelMouseEnter', activePanel, pos);	
							hoveredPanel = activePanel;	
						}

						context.event('panelMouseOver', activePanel, pos);
						break;

					}
				}

				if(activePanel === undefined) {

					hoveredPanel && context.event('panelMouseLeave', hoveredPanel, pos);
					hoveredPanel = activePanel;
					dragInsideIndex = null;
				}
			},

			panelMouseEnter: function(panel, pos) {
				onMouseOver.call(panel);
			},

			panelMouseLeave: function(panel, pos) {
				onMouseOut.call(panel);
			},

			itemSelected: function(item) {
				if(itemParents[item.ref.id]) {
					// on item in panel selected
				}
			},
			
			itemUnselected: function(item) {
				if(itemParents[item.ref.id]) {
					// on item in panel unselected
				}
			},

			itemAttrChange: function(itemId, attr, value) {
				
				var panel = panels[itemId];
			
				if(panel && panelAttributes.indexOf(attr) > -1) {
					
					panel.ref[attr] = value;
					setPanelPos(panel, panel.ref.x, panel.ref.y)
				}

				var item = items[itemId]

				if(item && itemAttributes.indexOf(attr) > -1) {
					
					// the only attribute handled by panel module is parent // todo x,y pos in panel
					
					if(!util.is(value, 'undefined') && !util.is(value, 'null')) {
						
						if (item.ref[attr] !== value) {
							removeItemFromPanel(item);
						}

						item.ref[attr] = value;

						if(!panelItems[item.ref.parent])
							panelItems[item.ref.parent] = [];
					
						panelItems[item.ref.parent].splice(item.ref.x, 0, item);
						itemParents[item.ref.id] = item.ref.parent;

						it.container.attr({height: gv + it.titleBackground.getBBox().height / 2, width:  panelItems[item.id].length * gh});
						it.titleBackground.attr({width:  panelItems[item.id].length * gh});
						
						it.title.attr({translation: '' + ((it.container.getBBox().width - it.title.getBBox().width) / 2) + ',2'});
						it.titleShadow.attr({translation: '' + ((it.container.getBBox().width - it.title.getBBox().width) / 2 + 1) + ',3'});

						var bbox = it.container.getBBox();

						for(var i = 0, len = panelItems[item.id].length; i < len; i++) {
							
							var iterator = panelItems[item.id][i];
							iterator.ref.parent = item.id;
							
							iterator.selected = false;

							// TODO
							//iterator.handle.hover(onMouseOver, onMouseOut, it, it);
							//iterator.elements.hover(onMouseOver, onMouseOut, it, it);
					
							var	itemPos = posFromGrid(i, 0, iterator.ref.w, iterator.ref.h, bbox.x, bbox.y);

							iterator.handle.stop().attr({
								x: itemPos.x, 
								y: itemPos.y
							});

							iterator.elements.stop().attr({
								x: itemPos.x, 
								y: itemPos.y
							});	

							iterator.handle.show().animate({ opacity: 1}, 200, '>');
							iterator.elements.show().animate({ opacity: 1}, 200, '>');
						}
					} else {// panel is removed 
						removeItemFromPanel(item);
					}
				}
			}
		}
	}
	
});